////////////////////////////////////////////////////////////////////////////////
// Filename: L_d3dx11graphics.cpp
////////////////////////////////////////////////////////////////////////////////
#include "L_dx11graphics.h"

L_DX11Graphics::L_DX11Graphics()
{

}

L_DX11Graphics::~L_DX11Graphics()
{

}

bool L_DX11Graphics::Init(HWND Hwnd)
{
	HRESULT hr;

	DXGI_MODE_DESC bufferDesc;
	ZeroMemory(&bufferDesc, sizeof(DXGI_MODE_DESC));
	bufferDesc.Width = 800;
	bufferDesc.Height = 600;
	bufferDesc.RefreshRate.Numerator = 60;
	bufferDesc.RefreshRate.Denominator = 1;
	bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
	bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;

	DXGI_SWAP_CHAIN_DESC swapChainDesc;
	ZeroMemory(&swapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
	swapChainDesc.BufferDesc = bufferDesc;
	swapChainDesc.SampleDesc.Count = 1;
	swapChainDesc.SampleDesc.Quality = 0;
	swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	swapChainDesc.BufferCount = 1;
	swapChainDesc.OutputWindow = Hwnd;
	swapChainDesc.Windowed = TRUE; 
	swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;

	hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, NULL, NULL, NULL,
		D3D11_SDK_VERSION, &swapChainDesc, &SwapChain, &Device, NULL, &DeviceContext);

	if(FAILED(hr))
	{
		MessageBox(NULL, "Error creating Device and SwapChain", "Error", MB_OK | MB_ICONERROR);
		return false;
	}

	ID3D11Texture2D* BackBuffer;
	hr = SwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), (void**)&BackBuffer );
	if(FAILED(hr))
	{
		MessageBox(NULL, "Error getting buffer", "Error", MB_OK | MB_ICONERROR);
		return false;
	}

	hr = Device->CreateRenderTargetView( BackBuffer, NULL, &renderTargetView );
	BackBuffer->Release();
	if(FAILED(hr))
	{
		MessageBox(NULL, "Error creating RenderTargetView", "Error", MB_OK | MB_ICONERROR);
		return false;
	}

	DeviceContext->OMSetRenderTargets( 1, &renderTargetView, NULL );

	layout[0].AlignedByteOffset = 0;
	layout[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
	layout[0].InputSlot = 0;
	layout[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
	layout[0].InstanceDataStepRate = 0;
	layout[0].SemanticIndex = 0;
	layout[0].SemanticName = "POSITION";
	layout[1].AlignedByteOffset = 12;
	layout[1].Format = DXGI_FORMAT_R32G32_FLOAT;
	layout[1].InputSlot = 0;
	layout[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
	layout[1].InstanceDataStepRate = 0;
	layout[1].SemanticIndex = 0;
	layout[1].SemanticName = "TEXCOORD";
	LayoutNumElements = 2;


	ResourceManager = new L_DX11ResourceManager;
	ResourceManager->Init(Device);

	Renderer = new L_DX11Renderer;
	if(!Renderer->Init(Device, DeviceContext, renderTargetView, ResourceManager))
	{
		MessageBox(NULL, "Error init render system", "Error", MB_OK | MB_ICONERROR);
		return false;
	}

	if(!ResourceManager->InitTexture("L.jpg"))
	{
		MessageBox(NULL, "Error creating texture", "Error", MB_OK | MB_ICONERROR);
		return false;
	}

	if(!CalculateScene())
	{
		return false;
	}

	return true; 
}

bool L_DX11Graphics::CalculateScene()
{
	MyEffect = new L_DX11Effect;
	if(!MyEffect->Init(	Device, layout, LayoutNumElements, "Effects.fx", "VS", "vs_4_0", "Effects.fx", "PS", "ps_4_0"))
	{
		return false;
	}

	DeviceContext->VSSetShader(MyEffect->GetVertexShader(), 0, 0);
	DeviceContext->PSSetShader(MyEffect->GetPixelShader(), 0, 0);

	Vertex v[] =
	{
		Vertex( -1.0f, -1.0f, 0.5f, 0.0f, 1.0f),
		Vertex( -1.0f,  1.0f, 0.5f, 0.0f, 0.0f),
		Vertex(  1.0f, -1.0f, 0.5f, 1.0f, 1.0f),

		Vertex( -1.0f,  1.0f, 0.5f, 0.0f, 0.0f),
		Vertex(  1.0f,  1.0f, 0.5f, 1.0f, 0.0f),
		Vertex(  1.0f, -1.0f, 0.5f, 1.0f, 1.0f),
	};

	VB = new L_DX11VertexBuffer;
	VB->Init(Device, v, 6*sizeof(Vertex), true);

	DeviceContext->IASetInputLayout( MyEffect->GetLayout() );
	Renderer->SetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

	D3D11_VIEWPORT viewport;
	ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));

	viewport.TopLeftX = 0;
	viewport.TopLeftY = 0;
	viewport.Width = 800;
	viewport.Height = 600;

	DeviceContext->RSSetViewports(1, &viewport);

	return true;
}

void L_DX11Graphics::Render()
{
	Renderer->ClearScreen(1.0f, 1.0f, 1.0f, 0.0f);
	Renderer->SetSamplerState(D3D11_FILTER_MIN_MAG_MIP_LINEAR);
	Renderer->SetTexture("L.jpg");
	//Renderer->Render(VB, sizeof(Vertex));

	static L_Sprite tempSprite;
	tempSprite.SetPos(50, 50);
	tempSprite.SetSize(200, 200);
	tempSprite.SetTexCoords(float2(0.0f, 0.0f), float2(1.0f, 1.0f));

	Renderer->BeginDrawSprites();
	Renderer->DrawSprite(tempSprite);

	SwapChain->Present(0, 0);
	Sleep(1);
}
